//
//  CMBleTools.m
//  BluetoothTest
//
//  Created by Chen Ming on 2017/11/28.
//  Copyright © 2017year Bioland. All rights reserved.
//

#import "CMBleTools.h"

@implementation CMBleTools


//Convert hexadecimal to decimal       return NSInteger
+ (NSInteger)getDecimalByHex:(NSString *)hex
{
    return strtoul([hex UTF8String], 0, 16);
}

//Convert decimal to hexadecimal
+ (NSString *)ToHex:(int)tmpid
{
    NSString *nLetterValue;
    NSString *str =@"";
    int ttmpig;
    for (int i = 0; i<9; i++) {
        ttmpig=tmpid%16;
        tmpid=tmpid/16;
        switch (ttmpig)
        {
            case 10:
                nLetterValue =@"A";break;
            case 11:
                nLetterValue =@"B";break;
            case 12:
                nLetterValue =@"C";break;
            case 13:
                nLetterValue =@"D";break;
            case 14:
                nLetterValue =@"E";break;
            case 15:
                nLetterValue =@"F";break;
            default:
                nLetterValue = [NSString stringWithFormat:@"%u",ttmpig];
                
        }
        str = [nLetterValue stringByAppendingString:str];
        if (tmpid == 0) {
            break;
        }
    }
    //Not enough for one byte to scrape 0
    if(str.length == 1){
        return [NSString stringWithFormat:@"0%@",str];
    }else{
        return str;
    }
}

/**
 * Convert hexadecimal numbers to decimal numbers
 * @return NSString
 */
+ (NSString *)handStrtoulStr:(NSString *)str {
    /*
     Make sure each number of hexadecimal numbers is two
     */
    NSString *string = [self addZero:str withLength:2];
    NSString *rechargeInfo =  [NSString stringWithFormat:@"0x%@",string];
    rechargeInfo = [NSString stringWithFormat:@"%ld",strtoul([rechargeInfo UTF8String],0,16)];
    //Not enough for one byte to scrape 0
    if(rechargeInfo.length == 1){
        return [NSString stringWithFormat:@"0%@",rechargeInfo];
    }else{
        return rechargeInfo;
    }

    return rechargeInfo;
}

//String zeroing operation
+ (NSString *)addZero:(NSString *)str withLength:(int)length{
    NSString *string = nil;
    if (str.length==length) {
        return str;
    }
    if (str.length<length) {
        NSUInteger inter = length-str.length;
        for (int i=0;i< inter; i++) {
            string = [NSString stringWithFormat:@"0%@",str];
            str = string;
        }
    }
    return string;
}

/**
 * Convert hex data to an array
 *
 * @param data Hexadecimal data
 * @return Converted array
 */
+ (NSMutableArray *)convertDataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return nil;
    }
    // Insert the cut hexadecimal number into a mutable array
    NSMutableArray *dataArr = [NSMutableArray new];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        
        for (NSInteger i = 0; i < byteRange.length; i++) {
            
            // Cut the byte array into a string
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            
            // Since the hexadecimal data is 0X XXXX with two bytes as a single digit, it is necessary to perform zero-padding operation on the cut data.
            if ([hexStr length] == 2) {
                [dataArr addObject:hexStr];
            } else {
                [dataArr addObject:[NSString stringWithFormat:@"0%@",hexStr]];
            }
        }
    }];
    return dataArr;
}

+ (NSData *)getCheckSum:(NSString *)byteStr {
    int length = (int)byteStr.length/2;
    NSData *data = [self hexToBytes:byteStr];
    Byte *bytes = (unsigned char *)[data bytes];
    Byte sum = 0;
    for (int i = 0; i<length; i++) {
        sum += bytes[i];
    }
    int at = sum;
    //int sumT = sum;
    //int at = 256 -  sumT;
    
//    printf("Checksum：%d\n",at);
    if (at == 256) {
        at = 0;
    }
    NSString *str = [NSString stringWithFormat:@"%@%@",byteStr,[self ToHex:at]];
    return [self hexToBytes:str];
}

+ (NSData *)hexToBytes:(NSString *)str
{
    NSMutableData* data = [NSMutableData data];
    int idx;
    for (idx = 0; idx+2 <= str.length; idx+=2) {
        NSRange range = NSMakeRange(idx, 2);
        NSString* hexStr = [str substringWithRange:range];
        NSScanner* scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    }
    return data;
}
/** rounding    The first one is the passed in parameter     The second one is accurate to a few decimal places. */
+ (NSString *)notRounding:(float)price afterPoint:(int)position
{
    NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler
                                        decimalNumberHandlerWithRoundingMode:NSRoundPlain
                                                scale:position
                                                raiseOnExactness:NO
                                                raiseOnOverflow:NO
                                                raiseOnUnderflow:NO
                                                raiseOnDivideByZero:NO];
    NSDecimalNumber *ouncesDecimal;
    NSDecimalNumber *roundedOunces;
    
    ouncesDecimal = [[NSDecimalNumber alloc] initWithFloat:price];
    roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    return [NSString stringWithFormat:@"%@",roundedOunces];
}

+(NSString *)ReturnTureBrandOrInstrument:(NSString *)string AndmodelStyle:(ModelStyle)modelStyle
{
    NSString *str = nil;
    if (modelStyle == BrandStyle) {
        if ([string isEqualToString:HexZero]) {
            str = @"apple";
        }else if ([string isEqualToString:HexOne]){
            str = @"bioland";
        }else if ([string isEqualToString:HexTwo]){
            str = @"Haier";
        }else if ([string isEqualToString:HexThree]){
            str = @"other";
        }else if ([string isEqualToString:HexFour]){
            str = @"Millet";
        }else if ([string isEqualToString:HexFive]){
            str = @"Daotong";
        }else if ([string isEqualToString:HexSix]){
            str = @"KANWEI";
        }else{
            str = @"other";
        }
    }else if (modelStyle == InstrumentStyle){
        if ([string isEqualToString:HexTwo]) {
            str = @"Blood glucose meter";
        }else{
            str = @"Non-glucometer";
        }
    }
    return str;
}
+(NSString *)StringToASCII:(NSString *)string
{
    string = [self handStrtoulStr:string];
    int asciiCode = [string intValue];
    NSString *string1 =[NSString stringWithFormat:@"%c",asciiCode];
    return string1;
}
/** Get current time */
+ (NSString *)changeDateStringDateFormatStr:(NSString *)dateFormatStr{
    NSDate *currentDate = [NSDate date];//Get current time，date
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:dateFormatStr];
    NSString *dateString = [dateFormatter stringFromDate:currentDate];
    return dateString;
}
/** Send a blood glucose packet */
+(NSData *)SendDataWithCurrentDate:(PacketStyle)style{
    NSString *currentTime = [self changeDateStringDateFormatStr:@"YY MM dd HH mm ss"];
    NSString *s0 = @"5A";
    NSString *s1 = @"0A";
    NSString *s2;
    if (style == InformationPacketStyle) {
        s2 = @"00";
    }else if (style == DataPacketStyle){
        s2 = @"03";
    }
    NSArray *array = [currentTime componentsSeparatedByString:@" "];
    NSInteger sum = [self getDecimalByHex:s0] + [self getDecimalByHex:s1] + [self getDecimalByHex:s2];
    for (NSString *string in array) {
        sum += [string integerValue];
    }
    NSString *data = [self ToHex:(int)(sum+2)];
    data = [data substringWithRange:NSMakeRange(data.length - 2, 2)];
    NSString *sendData = [NSString stringWithFormat:@"%@%@%@",s0,s1,s2];
    for (NSString *string in array) {
        sendData = [NSString stringWithFormat:@"%@%@",sendData,[self ToHex:[string intValue]]];
    }
    sendData = [NSString stringWithFormat:@"%@%@",sendData,data];
    return [self getCheckSum:sendData];
}
/** Send blood pressure data packet */
+(NSData *)pressureSendDataWithCurrentDate:(prePacketStyle)style{
    NSString *currentTime = [self changeDateStringDateFormatStr:@"YY MM dd HH mm ss"];
    NSString *s0 = @"5A";
    NSString *s1 = @"0A";
    NSString *s2;
    if (style == preInfoPacketStyle) {
        s2 = @"00";
    }else if (style == preDataPacketStyle){
        s2 = @"03";
    }else if (style == preStartPacketStyle){
        s2 = @"01";
    }else if (style == preOverPacketStyle){
        s2 = @"05";
    }
    NSArray *array = [currentTime componentsSeparatedByString:@" "];
    NSInteger sum = [self getDecimalByHex:s0] + [self getDecimalByHex:s1] + [self getDecimalByHex:s2];
    for (NSString *string in array) {
        sum += [string integerValue];
    }
    NSString *data = [self ToHex:(int)(sum+2)];
    data = [data substringWithRange:NSMakeRange(data.length - 2, 2)];
    NSString *sendData = [NSString stringWithFormat:@"%@%@%@",s0,s1,s2];
    for (NSString *string in array) {
        sendData = [NSString stringWithFormat:@"%@%@",sendData,[self ToHex:[string intValue]]];
    }
    sendData = [NSString stringWithFormat:@"%@%@",sendData,data];
    return [self getCheckSum:sendData];
}


+ (NSString*) serializeNSData:(NSData*)data
{
    NSMutableString *str = [NSMutableString stringWithCapacity:64];
    NSUInteger length = [data length];
    char *bytes = malloc(sizeof(char) * length);
    
    [data getBytes:bytes length:length];
    
    for (int i = 0; i < length; i++)
    {
        [str appendFormat:@"%02.2hhX", bytes[i]];
    }
    free(bytes);
    
    return str;
}


+ (NSString*) serializeNSDataDisplay:(NSData*)data
{
    NSMutableString *str = [NSMutableString stringWithCapacity:64];
    NSUInteger length = [data length];
    char *bytes = malloc(sizeof(char) * length);
    
    [data getBytes:bytes length:length];
    
    for (int i = 0; i < length; i++)
    {
        if(i==0)
        {
            [str appendFormat:@"%02.2hhX", bytes[i]];
        }
        else
        {
            [str appendFormat:@" %02.2hhX", bytes[i]];
        }
        
    }
    free(bytes);
    
    return str;
}

@end
